﻿using Arm2015.WebUI.Infrastructure;
using DevExpress.Data.Linq;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxGridLookup;
using DevExpress.Web.ASPxGridView;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;

namespace Arm2015.WebUI.App_Modules
{
    public partial class Journal : System.Web.UI.Page
    {
        private bool IsRedactMode
        {
            get
            {
                return gridJournal.IsEditing;
            }

        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack && !IsCallback)
            {
                cbContracts.Value = SessionManager.SelectedContractId;
                cbContracts_SelectedIndexChanged(cbContracts, new EventArgs());
            }
            if (IsCallback && !IsRedactMode)
            {
                DatabindGrid((int)cbContracts.Value);
            }
        }

        protected void cbContracts_SelectedIndexChanged(object sender, EventArgs e)
        {
            var cb = (ASPxComboBox)sender;
            var contractId = (int)cb.Value;

            var oldContractId = SessionManager.SelectedContractId;

            SessionManager.SelectedContractId = contractId;
            SessionManager.SelectedContractorId = SessionManager.CurrentContractorInfo.CONTRACTS.FirstOrDefault(x => x.C_CONTRACT == contractId).C_CONTRACTOR;

            gridJournal.FilterExpression = null;
            DatabindGrid(oldContractId);
        }

        protected void gridJournal_StartRowEditing(object sender, DevExpress.Web.Data.ASPxStartRowEditingEventArgs e)
        {
            var journalId = e.EditingKeyValue;
            var row = gridJournal.IsEditing
                ? (Models.Journal.Row)gridJournal.GetRow(gridJournal.EditingRowVisibleIndex)
                : new Models.Journal.Row { C_JOURNAL = 0 };
            SessionManager.EditJournalRow = row;
        }
        
        protected void gridJournal_BeforeGetCallbackResult(object sender, EventArgs e)
        {
            if (!IsRedactMode) return;

            var row = SessionManager.EditJournalRow;

            var lcMakers = (ASPxGridLookup)gridJournal.FindEditRowCellTemplateControl((GridViewDataColumn)gridJournal.Columns["N_MAKER"], "lcMakers");
            lcMakers.Value = row.C_MAKER;

            var lcObjects = (ASPxGridLookup)gridJournal.FindEditRowCellTemplateControl((GridViewDataColumn)gridJournal.Columns["N_OBJECT"], "lcObjects");
            lcObjects.Value = row.C_OBJECT;

            var lcElements = (ASPxGridLookup)gridJournal.FindEditRowCellTemplateControl((GridViewDataColumn)gridJournal.Columns["N_ELEMENT"], "lcElements");
            lcElements.Value = row.C_ELEMENT;

            var lcObjectElements = (ASPxGridLookup)gridJournal.FindEditRowCellTemplateControl((GridViewDataColumn)gridJournal.Columns["LOCATION"], "lcObjectElements");
            lcElements.Value = row.C_OBJECT_ELEMENT;
        }

        protected void gridJournal_CellEditorInitialize(object sender, ASPxGridViewEditorEventArgs e)
        {
            var row = SessionManager.EditJournalRow;
            var editor = e.Editor;

            if (e.Column.FieldName == "DATE")
            {
                var dateEditor=(ASPxDateEdit)e.Editor;
                dateEditor.MaxDate = DateTime.Now;
                if (gridJournal.IsEditing)
                    dateEditor.ClientEnabled = false;
            }
            if (e.Column.FieldName == "WORK_VALUE")
            {
                var ed=(ASPxSpinEdit)editor;
                ed.DecimalPlaces = row.DECIMAL_PLACES;
                ed.DisplayFormatString = string.Format("{{0:f{0}}}", row.DECIMAL_PLACES);
            }
        }

        /**/
        private void DatabindGrid(int contractId)
        {
            var sessionKey = "SELECTED_JOURNAL";
            var sessionValue = Session[sessionKey];
            var selectedContractId = SessionManager.SelectedContractId;

            if (sessionValue == null || selectedContractId != contractId)
            {
                LinqServerModeSource lsms = new LinqServerModeSource() { KeyExpression = "C_JOURNAL" };
                lsms.QueryableSource = GetJournal();

                Session[sessionKey] = lsms;
            }

            gridJournal.DataSource = (LinqServerModeSource)Session[sessionKey];

            gridJournal.DataBind();
        }

        /**/
        public List<Models.ContractInfo> GetContracts()
        {
            var userInfo = SessionManager.CurrentUserInfo;
            var userRole = (Models.Enums.UserRole)userInfo.C_ROLE;
            if (userRole == Models.Enums.UserRole.User)
            {
                return SessionManager.CurrentContractorInfo.CONTRACTS;
            }
            else
            {
                return new List<Models.ContractInfo>();
            }
        }

        private IQueryable<Models.Journal.Row> GetJournal()
        {
            var contractId = SessionManager.SelectedContractId;
            var dateStart = SessionManager.JournalDateStart;
            var dateEnd = SessionManager.JournalDateEnd;

            return Storage.Journal.GetJournal(contractId, dateStart, dateEnd);
        }

        public IQueryable GetContractorMakers()
        {
            var contractorId = SessionManager.SelectedContractorId;
            return Storage.AppCache.D_MAKERS
                .Where(x => x.C_CONTRACTOR == contractorId && x.IS_ACTIVE)
                .Select(x => new
                {
                    C_MAKER = x.C_MAKER,
                    N_MAKER = x.N_MAKER
                });
        }

        public IQueryable GetContractObjects()
        {
            var contractId=SessionManager.SelectedContractId;
            return Storage.AppCache.D_OBJECTS.Where(x => x.C_CONTRACT == contractId)
                .Select(x => new
                {
                    C_OBJECT = x.C_OBJECT,
                    CODE = x.CODE,
                    N_OBJECT = x.N_OBJECT
                });
        }

        public IQueryable GetElements()
        {
            var row = SessionManager.EditJournalRow;
            return Storage.AppCache.D_ELEMENTS.Where(x => x.C_OBJECT == row.C_OBJECT).Select(x => new
            {
                C_ELEMENT = x.C_ELEMENT,
                N_ELEMENT = x.N_ELEMENT,
                N_TYPE_ELEMENT = x.N_TYPE_ELEMENT
            }).Distinct().OrderBy(x => x.N_ELEMENT);
        }

        public IQueryable GetObjectElements(int objectId, int elementId)
        {
            return Storage.AppCache.D_ELEMENTS
                .Where(x => x.C_OBJECT == objectId && x.C_ELEMENT == elementId)
                .Select(x => new
            {
                C_OBJECT_ELEMENT = x.C_OBJECT_ELEMENT,
                LOCATION = x.LOCATION,
                BEGKM = x.BEGKM,
                ENDKM = x.ENDKM
            }).Distinct();
        }

        public IQueryable GetObjectElementWorks(int contractId, int monthId, int objectElementId)
        {
            //TODO: Попытаться вынести в кеш по контракту и месяцу
            var context = new Storage.DataEntities();

            var result = context.TEMP_SMETA
                .Where(x => x.C_CONTRACT == contractId && x.C_OBJECT_ELEMENT == objectElementId)
                .Join(context.S_CICLIC_DETAIL.Where(x => x.C_MONTH == monthId || x.C_MONTH == monthId - 1 || x.C_MONTH == monthId + 1), ts => ts.C_CICLIC, scd => scd.C_CICLIC, (ts, scd) => new
                {
                    C_WORK = ts.C_WORK,
                    N_WORK = ts.S_WORK.N_WORK,
                    PRIORITET = scd.C_MONTH == monthId ? 1 : (scd.C_MONTH == monthId - 1 || scd.C_MONTH == monthId + 1) ? 2 : 0
                })
                .Distinct();

            return result.OrderBy(x=>new{x.N_WORK, x.PRIORITET});
        }

        

        
    }
}